package org.convallaria.system.biz.service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * Token黑名单服务接口
 * 
 * @author convallaria
 * @since 1.0.0
 */
public interface TokenBlacklistService {

    /**
     * 将Token加入黑名单
     * 
     * @param token Token
     * @param reason 加入黑名单的原因
     * @param expireTime 过期时间
     */
    void addToBlacklist(String token, String reason, LocalDateTime expireTime);

    /**
     * 将Token加入黑名单（使用默认过期时间）
     * 
     * @param token Token
     * @param reason 加入黑名单的原因
     */
    void addToBlacklist(String token, String reason);

    /**
     * 检查Token是否在黑名单中
     * 
     * @param token Token
     * @return 是否在黑名单中
     */
    boolean isBlacklisted(String token);

    /**
     * 从黑名单中移除Token
     * 
     * @param token Token
     */
    void removeFromBlacklist(String token);

    /**
     * 批量将Token加入黑名单
     * 
     * @param tokens Token列表
     * @param reason 加入黑名单的原因
     */
    void addToBlacklist(List<String> tokens, String reason);

    /**
     * 清理过期的黑名单Token
     */
    void cleanExpiredTokens();

    /**
     * 获取黑名单统计信息
     * 
     * @return 统计信息
     */
    BlacklistStatistics getStatistics();

    /**
     * 黑名单统计信息
     */
    @lombok.Data
    @lombok.Builder
    @lombok.NoArgsConstructor
    @lombok.AllArgsConstructor
    class BlacklistStatistics {
        private long totalCount;
        private long activeCount;
        private long expiredCount;
        private LocalDateTime lastCleanTime;

        public static BlacklistStatistics empty() {
            return BlacklistStatistics.builder().build();
        }
    }

    /**
     * 黑名单原因枚举
     */
    enum BlacklistReason {
        LOGOUT("用户主动登出"),
        FORCE_LOGOUT("管理员强制登出"),
        PASSWORD_CHANGE("密码修改"),
        ACCOUNT_LOCK("账户锁定"),
        SECURITY_VIOLATION("安全违规"),
        TOKEN_EXPIRED("Token过期"),
        SUSPICIOUS_ACTIVITY("可疑活动"),
        ADMIN_REVOKE("管理员撤销");

        private final String description;

        BlacklistReason(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }
}
